package com.own.business.wechat.mobile.util;

import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.own.business.wechat.base.entity.po.WechatUser;
import com.own.business.wechat.base.service.WechatUserService;
import com.own.business.wechat.base.util.WechatCodeUtil;
import com.own.business.wechat.mobile.constant.ConstantWechatMobile;
import com.own.business.wechat.mobile.em.WechatMobileExceptionEnum;
import com.own.business.wechat.mobile.exception.WechatMobileException;
import com.own.business.wechat.mobile.propertry.WechatMobileProperties;
import com.own.business.wechat.mobile.service.WechatMobileAuthenticationService;
import com.own.component.store.core.Store;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.Duration;

/**
 * WechatMobileUtil
 *
 * @author chenxueli
 * @date 2023-06-30 10:41:05
 */
@Slf4j
@Component
public class WechatMobileUtil {

    @Resource
    private WechatMobileProperties wechatMobileProperties;
    @Resource
    private Store<String> store;

    @Resource
    private WechatMobileAuthenticationService wechatMobileAuthenticationService;
    @Resource
    private WechatUserService wechatUserService;

    /**
     * 根据code获取openId
     *
     * @param code code
     * @return openId
     */
    public String getOpenId(String code) {
        var api = ConstantWechatMobile.Api.GET_ACCESS_TOKEN_API
                .replace(ConstantWechatMobile.Field.APP_ID, wechatMobileProperties.getAppId())
                .replace(ConstantWechatMobile.Field.APP_SECRET, wechatMobileProperties.getAppSecret())
                .replace(ConstantWechatMobile.Field.CODE, code);
        var body = HttpRequest.get(api).execute().body();
        // 解析数据
        var jsonObject = resolve(body);
        // 转换数据（数据需要存档）
        wechatMobileAuthenticationService.saveOfJson(code, jsonObject);
        // 将数据保存到缓存中
        var openId = jsonObject.getString("openid");
        var accessToken = jsonObject.getString("access_token");
        var expire = jsonObject.getInteger("expires_in");
        // 将openId的token信息存入缓存
        store.value().set(openId, accessToken, Duration.ofSeconds(expire));
        // 返回数据
        return openId;
    }

    /**
     * 根据openId获取用户信息
     *
     * @param openId openId
     * @return 用户信息
     */
    public WechatUser getUserInfo(String openId) {
        // 获取accessToken的信息
        var accessToken = store.value().get(openId);
        if (StringUtils.isBlank(accessToken)) {
            throw new WechatMobileException(WechatMobileExceptionEnum.INVALID_TOKEN);
        }
        var api = ConstantWechatMobile.Api.GET_USER_INFO_API
                .replace(ConstantWechatMobile.Field.OPEN_ID, openId)
                .replace(ConstantWechatMobile.Field.TOKEN, accessToken);
        var body = HttpRequest.get(api).execute().body();
        // 解析数据
        var jsonObject = resolve(body);
        // 保存信息
        return wechatUserService.save(wechatMobileProperties.getAppId(), openId, wechatUser -> {
            wechatUser.setOpenId(jsonObject.getString("openid"));
            wechatUser.setNickname(jsonObject.getString("nickname"));
            wechatUser.setSex(jsonObject.getInteger("sex"));
            wechatUser.setProvince(jsonObject.getString("province"));
            wechatUser.setCity(jsonObject.getString("city"));
            wechatUser.setCountry(jsonObject.getString("country"));
            wechatUser.setAvatar(jsonObject.getString("headimgurl"));
            wechatUser.setUnionId(jsonObject.getString("unionid"));
        });
    }

    /**
     * 解析响应数据
     *
     * @param body 响应数据
     * @return 解析后的数据
     */
    private JSONObject resolve(String body) {
        var jsonObject = JSON.parseObject(body);
        var errCode = jsonObject.getInteger("errcode");
        if (errCode != null) {
            var em = WechatCodeUtil.check(errCode);
            if (em.success()) {
                return jsonObject;
            }
            throw new WechatMobileException(em.desc());
        }
        return jsonObject;
    }

}
